#include "StdAfx.h"
#include "xtLineSysRevise.h"
#include "DDReadWriteFile.h"
#include "xhHubCap.h"

xtLineSysRevise::xtLineSysRevise(void)
{
	m_bReviseLine = FALSE;
}

xtLineSysRevise::~xtLineSysRevise(void)
{
}



int xtLineSysRevise::Revise(BYTE *pData,zkLineBitInfo *pLineBit)
{
	if( !m_bReviseLine ) return 0;

	int i = 0;
	zkSysReviseItem *pItem =  m_xSysReviseItem;

	switch( pLineBit->nImgDefine )
	{
	case eImage_Define_Img16:
		{
			WORD *pwData = (WORD*)pData;
            for(i=0;i<pLineBit->nWidth;i++)
			{
				if( pwData[i] < pItem[0].pdwLinePixel[i] )
				{
                    pwData[i] = 0;
				}
				else if( pwData[i] < pItem[1].pdwLinePixel[i] )
				{
                    pwData[i] = (WORD)( pItem[0].dwItemPixelAvg + ( pwData[i] - pItem[0].pdwLinePixel[i] ) * pItem[0].pfK[i] );
				}
				else if( pwData[i] < pItem[2].pdwLinePixel[i] )
				{
					pwData[i] = (WORD)( pItem[1].dwItemPixelAvg + ( pwData[i] - pItem[1].pdwLinePixel[i] ) * pItem[1].pfK[i] );
				}
				else if( pwData[i] < pItem[3].pdwLinePixel[i] )
				{
					pwData[i] = (WORD)( pItem[2].dwItemPixelAvg + ( pwData[i] - pItem[2].pdwLinePixel[i] ) * pItem[2].pfK[i] );
				}
				else if( pwData[i] < pItem[4].pdwLinePixel[i] )
				{
					pwData[i] = (WORD)( pItem[3].dwItemPixelAvg + ( pwData[i] - pItem[3].pdwLinePixel[i] ) * pItem[3].pfK[i] );
				}
				else if( pwData[i] < pItem[5].pdwLinePixel[i] )
				{
					pwData[i] = (WORD)( pItem[4].dwItemPixelAvg + ( pwData[i] - pItem[4].pdwLinePixel[i] ) * pItem[4].pfK[i] );
				}
				else if( pwData[i] < pItem[6].pdwLinePixel[i] )
				{
					pwData[i] = (WORD)( pItem[5].dwItemPixelAvg + ( pwData[i] - pItem[5].pdwLinePixel[i] ) * pItem[5].pfK[i] );
				}
				else if( pwData[i] < pItem[7].pdwLinePixel[i] )
				{
					pwData[i] = (WORD)( pItem[6].dwItemPixelAvg + ( pwData[i] - pItem[6].pdwLinePixel[i] ) * pItem[6].pfK[i] );
				}
				else if( pwData[i] < pItem[8].pdwLinePixel[i] )
				{
					pwData[i] = (WORD)( pItem[7].dwItemPixelAvg + ( pwData[i] - pItem[7].pdwLinePixel[i] ) * pItem[7].pfK[i] );
				}
				else if( pwData[i] < pItem[9].pdwLinePixel[i] )
				{
					pwData[i] = (WORD)( pItem[8].dwItemPixelAvg + ( pwData[i] - pItem[8].pdwLinePixel[i] ) * pItem[8].pfK[i] );
				}
				else
				{
					pwData[i] = (1<<pLineBit->nBitPerSample) - 1;
				}
			}
		}
		break;
	case eImage_Define_Img8:
		{

		}
		break;
	default:
		break;
	}
	
	return 0;
}








int xtLineSysRevise::StartRevise(void *pVoid,zkLineBitInfo *pLineBit)
{
	m_bReviseLine = FALSE;

	zkSysReviseParam *pParam = (zkSysReviseParam*)pVoid;
	if( pParam->nGrades < 2 || pParam->nGrades > DD_MAX_GRADES )
	{
		return DD_ERR_PARAMETER;
	}
	if( pParam->nCapFrameCount < 5 )
	{
		pParam->nCapFrameCount = 5; 
	}
	if( pParam->nCapFrameCount > 200 )
	{
		pParam->nCapFrameCount = 200;
	}

	memcpy( &(m_xSysReviseFile.xReviseParam),pVoid,sizeof(zkSysReviseParam) );

	int nGrades = m_xSysReviseFile.xReviseParam.nGrades;
	
	m_nWidth = pLineBit->nWidth;
	int nBufSize = nGrades * m_nWidth;
	nBufSize *= ( sizeof(DWORD) + sizeof(float) );
	if( !m_xBufBlock.Allocate(nBufSize) )
	{
		return DD_ERR_NEWBUFFER;
	}

    BYTE *pTemp = m_xBufBlock.pBuffer;

	for(int i=0;i<nGrades; i++ )
	{
       m_xSysReviseItem[i].pdwLinePixel = (DWORD*)pTemp;
	   pTemp += ( m_nWidth * sizeof(DWORD) );
	   m_xSysReviseItem[i].pfK = (float*)pTemp;
	   pTemp += ( m_nWidth * sizeof(float) );
	}

	return 0;
}

int xtLineSysRevise::SetGrade(int nGrade)
{
	if( nGrade < 0 || nGrade >= m_xSysReviseFile.xReviseParam.nGrades )
	{
		return DD_ERR_PARAMETER;
	}
	m_nGrade = nGrade;

	m_xSysReviseItem[nGrade].nCapTimes      = 0;
	m_xSysReviseItem[nGrade].nGrade         = nGrade;
	m_xSysReviseItem[nGrade].nHeight        = 1;
	m_xSysReviseItem[nGrade].nWidth         = m_nWidth;
	m_xSysReviseItem[nGrade].dwItemPixelAvg = 0;

	DWORD *pdw = (DWORD*)m_xSysReviseItem[nGrade].pdwLinePixel;
	float *pf  = (float*)m_xSysReviseItem[nGrade].pfK;

	memset(pdw,0,sizeof(DWORD)*m_nWidth);
	memset(pf, 0,sizeof(float)*m_nWidth);

	return 0;
}

int xtLineSysRevise::SetLineData(BYTE *pData,zkLineBitInfo *pLineBit)
{
	if( m_nWidth != pLineBit->nWidth )
	{
		return DD_ERR_PARAMETER;
	}

	zkSysReviseItem *pItem = &( m_xSysReviseItem[m_nGrade] ); 
	pItem->nCapTimes++;

	DWORD *pdw = (DWORD*)( pItem->pdwLinePixel );

	if( eImage_Define_Img16 == pLineBit->nImgDefine )
	{
		WORD *pwData = (WORD*)pData;
		for(int i=0;i<m_nWidth;i++)
		{
			pdw[i] += pwData[i];
		}
	}
	else if( eImage_Define_Img8 == pLineBit->nImgDefine )
	{		
		for(int i=0;i<m_nWidth;i++)
		{
			pdw[i] += pData[i];
		}
	}

	return 0;
}


int xtLineSysRevise::SetReviseFile(char *pFileName)
{
	if( NULL == pFileName )
	{
		return DD_ERR_PARAMETER;
	}
	if( m_nGrade != (m_xSysReviseFile.xReviseParam.nGrades-1) )
	{
		return DD_ERR_PARAMETER;
	}
	sprintf(m_szReviseFile,pFileName);

	return 0;
}


int xtLineSysRevise::CreateRevise()
{
	m_bReviseLine = FALSE;

	int i,j;
    int nGrades = m_xSysReviseFile.xReviseParam.nGrades;
	if( (nGrades-1) != m_nGrade )
	{
		return -1;
	}

	zkSysReviseItem *pItem = NULL;
	DWORD *pdw = NULL,*pdw2 = NULL;
	float *pf  = NULL;

	for(i=0;i<nGrades;i++)
	{
        pItem = &( m_xSysReviseItem[i] );
		if( pItem->nCapTimes < 1 )
		{
			return -1;
		}
		pItem->dwItemPixelAvg = 0;

		pdw = (DWORD*)pItem->pdwLinePixel;

		for(j=0;j<m_nWidth;j++)
		{
			pdw[j] /= pItem->nCapTimes;

			pItem->dwItemPixelAvg += pdw[j];
		}

		pItem->dwItemPixelAvg /= m_nWidth;
	}

	DWORD h,p;

	int nKGrades = nGrades - 1;
	for(i=0;i<nKGrades;i++)
	{
		pItem = &( m_xSysReviseItem[i] );
		pf    = (float*)pItem->pfK;

		pdw   = m_xSysReviseItem[i].pdwLinePixel;
		pdw2  = m_xSysReviseItem[i+1].pdwLinePixel;

		if( m_xSysReviseItem[i+1].dwItemPixelAvg < m_xSysReviseItem[i].dwItemPixelAvg )
		{
			h = 0;
		}
		else
		{
			h = m_xSysReviseItem[i+1].dwItemPixelAvg - m_xSysReviseItem[i].dwItemPixelAvg;
		}

		for(j=0;j<m_nWidth;j++)
		{
            if( pdw2[j] <= pdw[j] )
			{
                pf[j] = 0;
			}
			else
			{
				p = pdw2[j] - pdw[j];

				pf[j] = (float)h;
				pf[j] /= p;
			}
		}
	}

	int nRet = 0;

	do 
	{
		sprintf( m_xSysReviseFile.szPlugDesc,( (xhHubCap*)this )->m_xUseDevDesc.cDeviceName );

		m_xSysReviseFile.nHeight = 1;
		m_xSysReviseFile.nWidth  = m_nWidth;

		DDReadWriteFile xFile;
		if( 0 != xFile.DDCreateFile(m_szReviseFile,FALSE) )
		{
			nRet = -1;
			break;
		}

		nRet = xFile.DDOperatorFile( (BYTE*)&m_xSysReviseFile,sizeof(zkReviseFileInfo),NULL,FALSE);
		if( nRet != 0)
		{
			break;
		}

		int nGrades = m_xSysReviseFile.xReviseParam.nGrades;
		nRet = xFile.DDOperatorFile( (BYTE*)m_xSysReviseItem,sizeof(zkSysReviseItem)*nGrades,NULL,FALSE);
		if( nRet != 0)
		{
			break;
		}

		int nBufSize = nGrades * m_nWidth;
		nBufSize *= ( sizeof(DWORD) + sizeof(float) );
		nRet = xFile.DDOperatorFile( m_xBufBlock.pBuffer,nBufSize,NULL,FALSE);
		if( nRet != 0)
		{
			break;
		}

		m_bReviseLine = TRUE;

	} while (false);

	return nRet;
}

int xtLineSysRevise::SelectFile(char *pFile,int nCreateRevise)
{
	m_bReviseLine = FALSE;

	int nRet = 0;

	do 
	{
		if( NULL == pFile )
		{
			break;
		}


		DDReadWriteFile xFile;

		if( 0 != xFile.DDCreateFile(pFile) )
		{
			nRet = -1;
			break;
		}

		nRet = xFile.DDOperatorFile( (BYTE*)&m_xSysReviseFile,sizeof(zkReviseFileInfo) );
		if( nRet != 0)
		{
			break;
		}

		int nGrades = m_xSysReviseFile.xReviseParam.nGrades;
		if( nGrades > DD_MAX_GRADES )
		{
			nRet = DD_ERR_PARAMETER;
			break;
		}
		if( memcmp( m_xSysReviseFile.szPlugDesc,( (xhHubCap*)this )->m_xUseDevDesc.cDeviceName,DDDEVNAMELEN ) != 0 )
		{
			nRet = DD_ERR_PARAMETER;
			break;
		}
		if( m_xSysReviseFile.nWidth != ( (xhHubCap*)this )->m_xLineBit.nWidth )
		{
			nRet = DD_ERR_PARAMETER;
			break;
		}

		memset(m_xSysReviseItem,0,sizeof(m_xSysReviseItem));
		nRet = xFile.DDOperatorFile( (BYTE*)m_xSysReviseItem,sizeof(zkSysReviseItem)*nGrades );
		if( nRet != 0)
		{
			break;
		}

		int nBufSize = nGrades * m_xSysReviseFile.nWidth;
		nBufSize *= ( sizeof(DWORD) + sizeof(float) );
		if( !m_xBufBlock.Allocate(nBufSize) )
		{
			nRet = DD_ERR_NEWBUFFER;
			break;
		}

		nRet = xFile.DDOperatorFile( m_xBufBlock.pBuffer,nBufSize );
		if( nRet != 0)
		{
			break;
		}

		BYTE *pTemp = m_xBufBlock.pBuffer;
		for(int i=0;i<nGrades; i++ )
		{
			m_xSysReviseItem[i].pdwLinePixel = (DWORD*)pTemp;
			pTemp += ( m_nWidth * sizeof(DWORD) );
			m_xSysReviseItem[i].pfK = (float*)pTemp;
			pTemp += ( m_nWidth * sizeof(float) );
		}

		m_bReviseLine = TRUE;

	}while(false);

	return nRet;
}

int xtLineSysRevise::GetReviseFileInfo(char *pFileName,void *pVoid)
{
	int nRet = 0;

	do 
	{
		if( NULL == pVoid )
		{
			nRet = DD_ERR_PARAMETER;
			break;
		}

		DDReadWriteFile xFile;

		if( 0 != xFile.DDCreateFile(pFileName) )
		{
			nRet = -1;
			break;
		}

		zkReviseFileInfo xSysReviseFile;

		nRet = xFile.DDOperatorFile( (BYTE*)&xSysReviseFile,sizeof(zkReviseFileInfo) );
		if( nRet != 0)
		{
			break;
		}

		int nGrades = xSysReviseFile.xReviseParam.nGrades;
		if( nGrades > DD_MAX_GRADES )
		{
			nRet = DD_ERR_PARAMETER;
			break;
		}
		if( memcmp( xSysReviseFile.szPlugDesc,( (xhHubCap*)this )->m_xUseDevDesc.cDeviceName,DDDEVNAMELEN ) != 0 )
		{
			nRet = DD_ERR_PARAMETER;
			break;
		}
		if( xSysReviseFile.nWidth != ( (xhHubCap*)this )->m_xLineBit.nWidth )
		{
			nRet = DD_ERR_PARAMETER;
			break;
		}

		memcpy(pVoid,&(xSysReviseFile.xReviseParam),sizeof(zkSysReviseParam));

	}while(false);

	return nRet;
}